#pragma once

#include "math_utils.h"

#include <opencv2/opencv.hpp>

#define COURT_WIDTH 6.10
#define COURT_HEIGHT 13.40

#define IMG_WIDTH 3840
#define IMG_HEIGHT 2160
typedef struct {
    rect_t rect;
    float score;
} ball_result_t;


typedef struct {
    point_t corner_points[4];
    point_t basket_rims_point[2];
    int view_id;
} ball_map_config_view_t;


typedef struct {
    com_cam_t *cams;
    int cam_num;
    com_point_t points[4]; // 4 corner pos in overhead view: lefttop, righttop, rightbottom, leftbottom
    com_vector_t vec_x;
    com_vector_t vec_y;
    com_vector_t vec_z;
    float vec_x_len;
    float vec_y_len;
    com_point_t rim_points[2]; // center points of 2 basket rims
    ball_map_config_view_t *cfg_views;
    int view_cnt;
    float avg_ball_width;
    float avg_ball_height;
    int   detect_count;
    int   cam_width;
    int   cam_height;
    int   out_stream_id;
    cv::Mat plane_2_radar_matrix;
    float cam_unit_x; // 1 meter distance in cam coords x
    float cam_unit_y; // 1 meter distance in cam coords y
    float cam_unit_z; // 1 meter distance in cam coords z
} ball_map_ctx_t;

typedef struct {
    com_cam_t *cams;
    ball_map_config_view_t *cfg_views;
    int view_cnt;
    int out_stream_id;
    point_t *norm_corner_points;
} ball_map_config_t;

typedef struct {
    point_t pos_2d;
    com_point_t pos_3d;
} ball_coord_t;

typedef struct {
    com_point_t corners[4];  // 四个角点：左上、右上、右下、左下
    float width;             // 球场宽度
    float height;            // 球场长度
    float net_height;        // 网高
    float net_position;      // 网的位置（从底线开始的偏移）
} court_boundary_t;

typedef struct {
   ball_coord_t pos;
   ball_result_t rect;
   com_vector_t rim_dists[2];
   com_point_t court_relative_pos;
   int avail;
   int valid_geometry;
   int filtered;
} ball_info_t;

ball_map_ctx_t *create_ball_map(ball_map_config_t cfg);
void destroy_ball_map(ball_map_ctx_t* map);
// res_views must be normalized
int get_ball_coord_by_views(ball_map_ctx_t *ctx, ball_result_t *res_views, ball_info_t *out);
void calcu_ball_court_center_offset(ball_map_ctx_t *ctx, ball_info_t *ball);
